package com.winshare.saleAssistant.service.impl;

import com.winshare.saleAssistant.constant.MaterialType;
import com.winshare.saleAssistant.dao.MaterialMapper;
import com.winshare.saleAssistant.domain.dto.req.BaseIdDTO;
import com.winshare.saleAssistant.domain.dto.req.MaterialCreateDTO;
import com.winshare.saleAssistant.domain.dto.req.MaterialQueryDTO;
import com.winshare.saleAssistant.domain.dto.req.MaterialUpdateDTO;
import com.winshare.saleAssistant.domain.dto.resp.MaterialRespDTO;
import com.winshare.saleAssistant.domain.entity.MaterialDO;
import com.winshare.saleAssistant.domain.query.MaterialQuery;
import com.winshare.saleAssistant.exception.BusinessException;
import com.winshare.saleAssistant.mapper.MaterialMapStruct;
import com.winshare.saleAssistant.service.MaterialService;
import com.winshare.saleAssistant.util.Page;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class MaterialServiceImpl implements MaterialService {

    private final MaterialMapper materialMapper;

    public MaterialServiceImpl(MaterialMapper materialMapper) {
        this.materialMapper = materialMapper;
    }

    @Override
    public void saveMaterial(MaterialCreateDTO materialCreateDTO) {
        materialCreateDTO.validMaterial();
        MaterialDO materialDO = MaterialMapStruct.INSTANCE.fromMaterialCreateDTO(materialCreateDTO);
        if(materialDO.getParentId() != null && materialDO.getParentId() !=0) {
            MaterialDO materialCondition = new MaterialDO();materialCondition.setId(materialDO.getParentId());
            MaterialDO materialDOParent = materialMapper.getMaterial(materialCondition);
            if(null == materialDOParent) {
                throw new BusinessException("父分类不存在！");
            }
            if(materialDOParent.getType() == MaterialType.file) {
                throw new BusinessException("不能在文件下面添加子分类或子文件。");
            }
        }
        if(checkMaterialExist(materialDO)) {
            throw new BusinessException("同一分类下面不能有名称相同的文件/同一分类下面不能有相同的子分类");
        }
        if(checkMaterialType(materialDO)) {
            throw new BusinessException("同一分类下面不能同时存在文件和子分类");
        }
        materialMapper.saveMaterial(materialDO);
    }

    @Override
    public void updateMaterial(MaterialUpdateDTO materialUpdateDTO) {
        materialUpdateDTO.validMaterial();
        MaterialDO materialDO = MaterialMapStruct.INSTANCE.fromMaterialUpdateDTO(materialUpdateDTO);
        if(materialDO.getParentId() != null && materialDO.getParentId() !=0) {
            MaterialDO materialCondition = new MaterialDO();materialCondition.setId(materialDO.getParentId());
            MaterialDO materialDOParent = materialMapper.getMaterial(materialCondition);
            if(null == materialDOParent) {
                throw new BusinessException("父分类不存在！");
            }
            if(materialDOParent.getType() == MaterialType.file) {
                throw new BusinessException("不能在文件下面添加子分类或子文件。");
            }
        }
        if(checkMaterialExist(materialDO)) {
            throw new BusinessException("同一分类下面不能有名称相同的文件/同一分类下面不能有相同的子分类");
        }
        if(checkMaterialType(materialDO)) {
            throw new BusinessException("同一分类下面不能同时存在文件和子分类");
        }
        materialMapper.updateMaterial(materialDO);
    }

    @Override
    public void deleteMaterial(BaseIdDTO baseIdDTO) {
        MaterialDO materialDO = MaterialMapStruct.INSTANCE.fromBaseIdDTO(baseIdDTO);
        MaterialDO materialDOInSql = materialMapper.getMaterial(materialDO);
        if(null == materialDOInSql) {
            throw new BusinessException("当前物料分类或文件不存在！");
        }
        if(checkChildMaterialExist(materialDO)) {
            throw new BusinessException("当前物料分类下面还有子分类或文件集，故不能删除");
        }
        materialMapper.deleteMaterial(materialDO);
    }

    @Override
    public MaterialRespDTO getMaterialDetail(BaseIdDTO baseIdDTO) {
        MaterialDO materialDO = MaterialMapStruct.INSTANCE.fromBaseIdDTO(baseIdDTO);
        MaterialDO materialDOInSql = materialMapper.getMaterial(materialDO);
        if(null == materialDOInSql) {
            throw new BusinessException("当前物料分类或文件不存在！");
        }
        MaterialRespDTO materialRespDTO = MaterialMapStruct.INSTANCE.fromMaterialDO(materialDOInSql);
        return materialRespDTO;
    }

    @Override
    public Page<MaterialRespDTO> getMaterialList(MaterialQueryDTO materialQueryDTO) {
        MaterialQuery materialQuery = MaterialMapStruct.INSTANCE.fromMaterialQueryDTO(materialQueryDTO);
        if(materialQuery.getParentId() == null) {
            materialQuery.setParentId(0);
        }
        materialQuery.setOffsetIndex(materialQueryDTO.getOffsetIndex());
        int totalCount = materialMapper.queryMaterialCount(materialQuery);
        Integer pageIndex = materialQueryDTO.getPageIndex();
        Integer pageSize = materialQueryDTO.getPageSize();
        if(0 == totalCount) {
            return new Page<>(pageIndex,pageSize,totalCount,new ArrayList<>());
        }
        List<MaterialDO> materialDOList = materialMapper.findMaterialByConditions(materialQuery);
        List<MaterialRespDTO> materialRespDTOList = MaterialMapStruct.INSTANCE.fromMaterialDOList(materialDOList);
        return new Page<>(pageIndex,pageSize,totalCount,materialRespDTOList);
    }

    private boolean checkChildMaterialExist(MaterialDO materialDO) {
        return materialMapper.countChildMaterial(materialDO) > 0;
    }

    private boolean checkMaterialExist(MaterialDO materialDO) {
        return materialMapper.countMaterial(materialDO) > 0;
    }

    private boolean checkMaterialType(MaterialDO materialDO) {
        return materialMapper.countMaterialType(materialDO) > 0;
    }
}
